package service

import (
	"fmt"
	"sync"
)

type Publisher struct {
	subscribers map[string]chan string
	mux         sync.Mutex
}

func NewPublisher() *Publisher {
	return &Publisher{
		subscribers: make(map[string]chan string),
		mux:         sync.Mutex{},
	}
}

func (p *Publisher) Subscribe(key string) chan string {
	p.mux.Lock()
	defer p.mux.Unlock()
	exist, ok := p.subscribers[key]
	if ok {
		return exist
	}

	ch := make(chan string)
	p.subscribers[key] = ch
	return ch
}

func (p *Publisher) UnSubscribe(key string) {
	p.mux.Lock()
	defer p.mux.Unlock()

	delete(p.subscribers, key)
}

func (p *Publisher) Publish(key string, message string) {
	p.mux.Lock()
	defer p.mux.Unlock()

	ch, ok := p.subscribers[key]
	if !ok {
		return
	}

	ch <- message
}

func (p *Publisher) PrintSubscribersInfo() {
	fmt.Printf("the subscribers are as follow:")
	for k, _ := range p.subscribers {
		fmt.Print(k + "\n")
	}
}
